#ifndef MODEL_RENDERER_H 
#define MODEL_RENDERER_H

#include "MeshRenderer.h"

#include <string>
#include <memory>
#include <vector>

using namespace std;

namespace geom
{
	class PolyMesh;
	class PolyModel;
}

namespace glutil
{
	class FreeCamera;
	/** Renders several instances of a given model (each composed of several meshes)*/
	class ModelRenderer
	{
		protected:
			/** Objects that will render each mesh the model has */
			vector<MeshRenderer> m_meshRenderers;
			float m_baseScale;
		public:
			/** Constructor
			  @param model Model to render */
			ModelRenderer(const geom::PolyModel& model,float baseScale=1.0f);
			/** Adds another instance of the model to be rendered in the 3D world 
			  @param m Instance information */
			void addInstance(const GLInstanceInfo & m);
			
			/** Removes all instances for this model */
			void clearInstances();

			/** Renders a specific instance
			 @param withMaterials Option to render the mesh with, or without materials
			  @param instance Instance ID */
			void render(int instance, bool withMaterials);

			/** Renders all instances in the model 
			 @param withMaterials Option to render the mesh with, or without materials*/
			void renderAll(bool withMaterials);
			/** Renders all models that fall inside the camera frustum, and are closer than a given distance
			 @param withMaterials Option to render the mesh with, or without materials
			 @param camera Camera to get the frustum from
			 @param maxDistance Maximum distance to render */
			void renderAll(bool withMaterials, const glutil::FreeCamera * camera, float maxDistance, int selectedTree);
			/** Updates the VBOs to store the current model data */
			void generateVertexBufferObjects();

			/** Constructs a renderer with one instance of size 1, with no rotation, and positioned at (0,0,0) */
			static ModelRenderer * simpleCenteredInstanceCreator(const geom::PolyModel &model);
	};
}

#endif
